package org.myOrg.spetrum.SpecificAlogrithm;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.myOrg.spetrum.combination.Tuple;
import org.myOrg.spetrum.spectrumStruct.SpectrumFactory;
import org.myOrg.spetrum.spectrumStruct.SpetrumAnalyseBase;
import org.myOrg.spetrum.spectrumStruct.TupleAnalyseStruct;
import org.myOrg.spetrum.testObject.TestSuite;
import org.myOrg.spetrum.testRun.TestRun;

public class SpectrumAnalysePath extends SpetrumAnalyseBase {
	
	private List<TupleAnalyseStruct> currentPaths;
	private int head;
	private int tail;
	private int middle;
	
	public SpectrumAnalysePath(TestRun run, int[] param,
			TestSuite wrongTestCases, TestSuite rightTestCases) {
		super(run, param, wrongTestCases, rightTestCases);
		this.id = SpectrumFactory.PATH;
	}

	public SpectrumAnalysePath() {
		// TODO Auto-generated constructor stub
		super();
		this.id = SpectrumFactory.PATH;
	}
	@Override
	public void init() {
		super.init();
		reSetPath();
	}

	public void reSetPath() {
		currentPaths = this.getLongestPath();
		tail = currentPaths.size() - 1;
		head  = middle = 0;
	}
	
	@Override
	public void doWrong(Tuple tuple){
		super.doWrong(tuple);
		head = middle + 1;
		if(head > tail)
			this.reSetPath();
		else
			middle = (head + tail)/2;
	}
	@Override
	public void doRight(Tuple tuple){
		super.doRight(tuple);
		tail = middle -1;
		if(tail < head)
			this.reSetPath();
		else
			middle = (head + tail)/2;
	}
	
	public List<TupleAnalyseStruct> getPath(TupleAnalyseStruct head){
		List<TupleAnalyseStruct> result = new ArrayList<TupleAnalyseStruct>();
		if(!head.isTested())
			result.add(head);
		
		List<TupleAnalyseStruct> temp = new ArrayList<TupleAnalyseStruct>();
		Iterator<TupleAnalyseStruct> directChilds = head.getDirectChilds().iterator();
		while(directChilds.hasNext()){
			TupleAnalyseStruct child = directChilds.next();
			List<TupleAnalyseStruct> childPaths = getPath(child);
			if(temp.size() < childPaths.size())
				temp = childPaths;
		}
		
		result.addAll(temp);
		return result;
	}
	
	public List<TupleAnalyseStruct> getLongestPath(){
		List<TupleAnalyseStruct> result = new ArrayList<TupleAnalyseStruct>();
		List<TupleAnalyseStruct> temp = new ArrayList<TupleAnalyseStruct>();
		Iterator<Tuple> heads = this.setUp.getCandidateHeadTuple().iterator();
		while(heads.hasNext()){
			TupleAnalyseStruct struct = this.getTupleManager().getTupleAnalyseStructByTuple(heads.next());
			temp = this.getPath(struct);
			if(temp.size() > result.size())
				result = temp;
		}
		return result;
	}
	
	@Override
	public Tuple getTestTuple() {
		return currentPaths.get(middle).getTuple();
	}
}
